package com.ming.liteflow.controller;

import com.github.benmanes.caffeine.cache.Cache;
import com.ming.common.beetl.cache.CacheSqlManagerUtil;
import com.ming.common.beetl.cache.CacheUtil;
import com.ming.common.beetl.util.Result;
import com.ming.common.beetl.util.SQLManagerUtil;
import com.ming.common.beetl.util.SqlUtil;
import com.ming.common.beetl.util.StrUtil;
import com.ming.common.dynamic.code.exception.BaseDynamicException;
import com.ming.common.dynamic.loader.MethodUtils;
import com.ming.common.dynamic.loader.SpringContextUtil;
import com.ming.common.dynamic.loader.bean_loader.DynamicBean;
import com.ming.common.dynamic.loader.class_loader.DynamicClass;
import com.ming.liteflow.cmp.node.BCmp;
import com.ming.liteflow.core.el.Flow;
import com.ming.liteflow.core.el.NodeInfoToELUtil;
import com.ming.liteflow.core.el.bus.*;
import com.ming.liteflow.core.exec.ELExecUtil;
import com.ming.liteflow.core.node.*;
import com.ming.liteflow.vo.NodeInfoVo;
import com.ming.liteflow.vo.Options;
import com.ming.liteflow.vo.SortBy;
import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
import com.yomahub.liteflow.builder.el.ELBus;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.page.PageResult;
import org.beetl.sql.core.query.LambdaQuery;
import org.beetl.sql.core.query.Query;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/liteflow/cmp")
public class LiteFlowCmpController {

    @Resource
    private SQLManager sqlManager;

    @PostMapping("/page")
    public Result<PageResult<NodeInfo>> page(@RequestBody NodeInfoVo vo){
        LambdaQuery<NodeInfo> lambdaQuery = sqlManager.lambdaQuery(NodeInfo.class);
        lambdaQuery.andEq(NodeInfo::getType, LambdaQuery.filterEmpty(vo.getType()));
        lambdaQuery.andLike(NodeInfo::getComponentId, LambdaQuery.filterLikeEmpty(vo.getComponentId()));
        lambdaQuery.andLike(NodeInfo::getComponentName, LambdaQuery.filterLikeEmpty(vo.getComponentName()));
        Options options = vo.getOptions();
        List<SortBy> sortBy = options.getSortBy();
        for (SortBy sort : sortBy) {
            if ("desc".equalsIgnoreCase(sort.getOrder())) {
                lambdaQuery.desc(StrUtil.camelToSnake(sort.getKey()));
            } else {
                lambdaQuery.asc(StrUtil.camelToSnake(sort.getKey()));
            }
        }
        PageResult<NodeInfo> page = lambdaQuery.page(options.getPage(), options.getItemsPerPage());
        return Result.OK(page);
    }

    @PostMapping("/list")
    public Result<List<NodeInfo>> list(@RequestBody NodeInfoVo vo){
        LambdaQuery<NodeInfo> lambdaQuery = sqlManager.lambdaQuery(NodeInfo.class);
        lambdaQuery.andEq(NodeInfo::getType, LambdaQuery.filterEmpty(vo.getType()));
        lambdaQuery.andLike(NodeInfo::getComponentId, LambdaQuery.filterLikeEmpty(vo.getComponentId()));
        lambdaQuery.andLike(NodeInfo::getComponentName, LambdaQuery.filterLikeEmpty(vo.getComponentName()));
        List<NodeInfo> list = lambdaQuery.select();
        return Result.OK(list);
    }

    @PostMapping("/add")
    public Result<Object> add(@RequestBody NodeInfo nodeInfo){
        LambdaQuery<NodeInfo> lambdaQuery = sqlManager.lambdaQuery(NodeInfo.class);
        lambdaQuery.andEq(NodeInfo::getComponentId, nodeInfo.getComponentId());
        long count = lambdaQuery.count();
        if(count > 0){
            return Result.error("组件ID重复");
        }
        nodeInfo.setEl(NodeInfoToELUtil.toEL(nodeInfo,false));
        nodeInfo.setElFormat(NodeInfoToELUtil.toEL(nodeInfo,true));
        int i = sqlManager.insert(NodeInfo.class, nodeInfo);
        return Result.OK("新增成功",i);
    }

    @PostMapping("/update")
    public Result<Object> update(@RequestBody NodeInfo nodeInfo){
        LambdaQuery<NodeInfo> lambdaQuery = sqlManager.lambdaQuery(NodeInfo.class);
        lambdaQuery.andNotEq(NodeInfo::getId, nodeInfo.getId());
        lambdaQuery.andEq(NodeInfo::getComponentId, nodeInfo.getComponentId());
        long count = lambdaQuery.count();
        if(count > 0){
            return Result.error("组件ID重复");
        }
        nodeInfo.setEl(NodeInfoToELUtil.toEL(nodeInfo,false));
        nodeInfo.setElFormat(NodeInfoToELUtil.toEL(nodeInfo,true));
        int i = sqlManager.updateById(nodeInfo);
        return Result.OK("更新成功", i);
    }

    @PostMapping("/delete")
    public Result<Integer> delete(@RequestBody NodeInfo nodeInfo){
        LambdaQuery<NodeInfo> lambdaQuery = sqlManager.lambdaQuery(NodeInfo.class);
        lambdaQuery.andEq(NodeInfo::getComponentId, nodeInfo.getComponentId());
        int i = lambdaQuery.delete();
        return Result.OK("删除成功",i);
    }

    @PostMapping("/exec")
    public Result<Object> exec(@RequestBody NodeInfo nodeInfo){
        LambdaQuery<NodeInfo> lambdaQuery = sqlManager.lambdaQuery(NodeInfo.class);
        lambdaQuery.andEq(NodeInfo::getId, nodeInfo.getId());
        NodeInfo info = lambdaQuery.single();
        try {
            CmpScriptUtil.createNode(info);
            String el = info.getEl();
            System.out.println("EL："+el);
            String execResult = ELExecUtil.exec(info);
            return Result.OK("执行成功",execResult);
        }catch (Exception e){
            e.printStackTrace();
            return Result.error(e.getMessage());
        }
    }

//    @GetMapping("/test/add")
//    public String testAdd(){
//        LambdaQuery<NodeInfo> query = sqlManager.lambdaQuery(NodeInfo.class);
//        query.andEq(NodeInfo::getComponentId, "cmp_a");
//        NodeInfo info = query.single();
//        CmpScriptUtil.createNode(info);
//        System.out.println(ELExecUtil.exec("THEN(cmp_a);"));
//
//        info.setScript(
//                "import com.yomahub.liteflow.script.ScriptExecuteWrap;\n" +
//                        "import com.yomahub.liteflow.script.body.JaninoCommonScriptBody;\n" +
//                        "\n" +
//                        "public class ScriptNodeAAAA implements JaninoCommonScriptBody {\n" +
//                        "    @Override\n" +
//                        "    public Void body(ScriptExecuteWrap scriptExecuteWrap) {\n" +
//                        "        System.out.println(\"2222222\");\n" +
//                        "        return null;\n" +
//                        "    }\n" +
//                        "}\n");
//        CmpScriptUtil.createNode(info);
//        System.out.println(ELExecUtil.exec("THEN(cmp_a);"));
//        return "null";
//    }


}
